package com.zros.modules.shiro.authc.aop;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zros.common.api.vo.Result;
import com.zros.common.constant.ResponseConstant;
import com.zros.common.exception.JeecgBootException;
import com.zros.modules.shiro.authc.JwtToken;
import com.zros.modules.shiro.vo.DefContants;

/**
 * @author Scott
 * @create 2018-07-12 15:56
 * @desc 鉴权登录拦截器
 **/
public class JwtFilter extends BasicHttpAuthenticationFilter {

	/**
	 * 执行登录认证
	 *
	 * @param request
	 * @param response
	 * @param mappedValue
	 * @return
	 */
	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
			try {
				executeLogin(request, response);
				return true;
			} 
			catch (Exception e) {
				//超时或者未登录时直接返回异常
				e.printStackTrace();
				HttpServletResponse httpServletResponse = (HttpServletResponse) response;
				httpServletResponse.setStatus(200);
				httpServletResponse.setCharacterEncoding("UTF-8");
				httpServletResponse.setContentType("application/json; charset=utf-8");
				PrintWriter out = null;
				try {
					out = httpServletResponse.getWriter();
					ObjectMapper mapper = new ObjectMapper();
					String mapJakcson = mapper.writeValueAsString(new Result<String>().error(ResponseConstant.UNAUTHORIZED));
					if(e.getMessage().equals("当前帐号在其他地点登录，您已被强制下线"))
					{
						mapJakcson = mapper.writeValueAsString(new Result<String>().error(ResponseConstant.chongfudenglu));
					}
					out.append(mapJakcson);
				} catch (IOException ie) {
					// logger.error(e.getMessage());
				} finally {
					if (out != null) {
						out.close();
					}
				}
				return false;
				//throw new AuthenticationException("Token失效，请重新登录", e);
			}
	}

	/**
	 *
	 */
	@Override
	protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String token = httpServletRequest.getHeader(DefContants.AUTHORIZATION);

		JwtToken jwtToken = new JwtToken(token);
		// 提交给realm进行登入，如果错误他会抛出异常并被捕获
		getSubject(request, response).login(jwtToken);
		
		//将当前用户放置进request请求里，@CurrentUser
		//setUserBean(request, response, token);
		
		// 如果没有抛出异常则代表登入成功，返回true
		return true;
	}

	/*
	 * private void setUserBean(ServletRequest request, ServletResponse response,
	 * String token) { if (this.userService == null) { this.userService =
	 * SpringContextUtils.getBean(IUserService.class); } String userAccount =
	 * JwtUtil.getUsername(token); User userBean =
	 * userService.queryUserByAccount(userAccount);
	 * request.setAttribute("currentUser", userBean); }
	 */
	/**
	 * 对跨域提供支持
	 */
	@Override
	protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		HttpServletResponse httpServletResponse = (HttpServletResponse) response;
		httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
		httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
		httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
		// 跨域时会首先发送一个option请求，这里我们给option请求直接返回正常状态
		if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
			httpServletResponse.setStatus(HttpStatus.OK.value());
			return false;
		}
		
		//判断请求的路径是否需要鉴权
		/*
		 * for (String urlMethod : Constant.METHOD_URL_SET) { String[] split =
		 * urlMethod.split(":"); if (split[0].equals(httpServletRequest.getRequestURI())
		 * && (split[1].equals(httpServletRequest.getMethod()) ||
		 * "RequestMapping".equals(split[1]))) { return true; } else if
		 * (split[0].contains("{")) { String uri = split[0].substring(0,
		 * split[0].indexOf("{")); if
		 * (httpServletRequest.getRequestURI().startsWith(uri)) { return true; } } }
		 */
		return super.preHandle(request, response);
	}
}
